using System;
using System.Collections;
using System.Windows.Forms;
using System.ComponentModel;
using System.Reflection;
using System.Diagnostics;

namespace CSettingsUI
{
    #region CustomDataBinding
    /// <summary>
    /// DataBinding is the bridge between <code>IPropertyConverterControl</code> and <code>PropertyInfo</code>. The Validation Events are also here implemented
    /// and invokes the corresponding methods for validation.
    /// </summary>
    public class CustomDataBinding
    {
        #region attributes
        public EventHandler ValueChanged;
        IPropertyConverterGui optionConveterGui;
        object source;
        System.Reflection.PropertyInfo propertyInfo;
        System.Reflection.MethodInfo methodInfoValidating;
        IPropertyConverterControl guiControl;
        #endregion

        public CustomDataBinding(object src, System.Reflection.PropertyInfo pi, IPropertyConverterControl ctl, IPropertyConverterGui optionConveterGui)
        {
            Debug.WriteLine("DataBinding");
            guiControl = ctl;
            this.propertyInfo = pi;
            this.source = src;
            this.optionConveterGui = optionConveterGui;
            //
            Bind();
        }


        #region public
        public void Bind()
        {
            Debug.WriteLine("Bind");

            if (!(guiControl is Control)) return;
            //
            Control control = (Control)guiControl;
            // data binding			
            control.DataBindings.Add("Value", source, propertyInfo.Name);
            // validating
            methodInfoValidating = source.GetType().GetMethod(propertyInfo.Name + "Validating", new Type[] { propertyInfo.PropertyType });
            if ((methodInfoValidating != null) && (methodInfoValidating.ReturnType.Equals(typeof(string))))
            {
                control.Validating -= new CancelEventHandler(control_Validating);
                control.Validating += new CancelEventHandler(control_Validating);
            }
            //
          
            control.Validated -= new EventHandler(control_Validated);
            control.Validated += new EventHandler(control_Validated);
        }
        #endregion

        #region events
        private void control_Validating(object sender, CancelEventArgs e)
        {
            Debug.WriteLine("control_Validating");
            string error = methodInfoValidating.Invoke(source, new object[] { guiControl.Value }) as string;
            if (error != string.Empty)
            {
                e.Cancel = true;
                //
                if (optionConveterGui != null)
                {
                    optionConveterGui.SetError((IPropertyConverterControl)sender, error);
                }
            }
        }
        private void control_Validated(object sender, EventArgs e)
        {
            Debug.WriteLine("control_Validated");
            if (optionConveterGui != null)
            {
                optionConveterGui.SetError((IPropertyConverterControl)sender, String.Empty);
            }
            //
            if (ValueChanged != null)
            {
                ValueChanged(this, EventArgs.Empty);
            }
        }
        #endregion
    }
    #endregion
}
